package com.amos.doublewriterconsistence.request.impl;

import com.alibaba.fastjson.JSONObject;
import com.amos.doublewriterconsistence.entity.Inventory;
import com.amos.doublewriterconsistence.request.Request;
import com.amos.doublewriterconsistence.service.InventoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Copyright 2020 心情如水. All rights reserved.
 *
 * @Package com.amos.consumer.service.impl
 * @ClassName InventoryServiceImpl
 * @Description 数据更新操作
 * 1. 先删除缓存中的数据
 * 2. 再更新数据库中的数据
 *
 * 比如说一个商品发生了交易，那么就要修改这个商品对应的库存
 * 此时就会发送请求过来，要求修改库存，那么这个可能就是所谓的data update request，数据更新请求
 *
 * @Author Amos
 * @Modifier
 * @Date 2020/2/19 0021 下午 21:34
 * @Version 1.0
 **/
public class InventoryDBRequest implements Request {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 商品库存
     */
    private Inventory inventory;

    /**
     * 商品库存Service
     */
    private InventoryService inventoryService;

    /**
     * 构造器
     *
     * @param inventory
     * @param inventoryService
     */
    public InventoryDBRequest(Inventory inventory, InventoryService inventoryService) {
        this.inventory = inventory;
        this.inventoryService = inventoryService;
    }

    /**
     * 库存数据库操作
     * 1. 先删除缓存中对应的数据
     * 2. 更新数据库中的数据
     */
    @Override
    public void process() {

        this.logger.info("===========日志===========: 数据库更新请求开始执行，商品id=" + inventory.getId() + ",商品名称name="+inventory.getName()+" 商品库存数量=" + inventory.getCount());

        /**
         * 场景说明：
         * 写请求过来，将写请求缓存到缓存队列中，并且开始执行写请求的具体操作（删除缓存中的数据，更新数据库，更新缓存）
         *
         */
        this.logger.info("数据库操作——移除缓存中的数据");

        // 首先删除缓存中的数据(删除redis中的缓存);
        this.inventoryService.removeInventoryCache(this.inventory.getId());

        // 为了模拟演示先删除了redis中的缓存，然后还没更新数据库的时候，读请求过来了，这里可以人工sleep一下
        try {
            this.logger.info("数据库操作——等待3秒操作");
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }

        /**
         * 场景说明：
         * 1、写请求删除缓存成功，则更新数据库，如果更新数据库失败，则直接返回，写请求结束 ，此时数据库中的值依旧是旧值，
         * 读请求过来后，发现缓存中没有数据， 则会直接向数据库中请求，同时将数据写入到缓存中，此时也不会出现数据一致性的问题
         */


        // 再更新数据库中的数据(// 修改数据库中的库存)
        this.logger.info("数据库操作——更新数据库中的数据");
        this.inventoryService.updateInventory(this.inventory);
    }

    /**
     * 接口返回库存记录的ID(获取商品id)
     *
     * @return
     */
    @Override
    public String getInventoryId() {
        return this.inventory.getId();
    }

    /**
     * 始终不更新
     *
     * @return
     */
//    @Override
//    public Boolean isForceRefresh() {
//        return Boolean.FALSE;
//    }
}
